﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace MediaWiki.Office.Model.Utilities
{
  public static class XmlUtils
  {
    public static bool? OnOffToBoolean(string value)
    {
      if (value == null)
        return null;

      bool result;
      if (bool.TryParse(value, out result))
        return result;

      int flag;
      if (int.TryParse(value, out flag))
        return Convert.ToBoolean(flag);

      if (value == "on")
        return true;
      if (value == "off")
        return false;

      throw new Exception(string.Format("Could not convert on/off value of {0} to boolean.", value));
    }

    public static bool? GetBoolean(this XElement valueElement)
    {
      if (valueElement == null)
        return null;

      XNamespace elementNS = valueElement.Name.Namespace;
      XAttribute valueAttribute = valueElement.Attribute(elementNS + "val");

      if (valueAttribute == null)
        return true;

      return OnOffToBoolean((string)valueAttribute);
    }

    public static T? GetValue<T>(this XElement valueElement) where T : struct
    {
      return GetValue<T>(valueElement, "val");
    }

    public static T? GetValue<T>(this XElement valueElement, string attributeName) where T : struct
    {
      if (valueElement == null)
        return null;

      XNamespace elementNS = valueElement.Name.Namespace;

      return GetValue<T>(valueElement, elementNS + attributeName);
    }

    public static T? GetValue<T>(this XElement valueElement, XName attributeName) where T : struct
    {
      string value = GetValue(valueElement, attributeName);

      if (value == null)
        return null;

      if (typeof(T).IsEnum)
        return (T)Enum.Parse(typeof(T), value, true);

      return (T?)Convert.ChangeType(value, typeof(T), null);
    }

    public static string GetValue(this XElement valueElement)
    {
      return GetValue(valueElement, "val");
    }

    public static string GetValue(this XElement valueElement, string attributeName)
    {
      if (valueElement == null)
        return null;

      XNamespace elementNS = valueElement.Name.Namespace;

      return GetValue(valueElement, elementNS + attributeName);
    }

    public static string GetValue(XElement valueElement, XName attributeName)
    {
      if (valueElement == null)
        return null;

      XAttribute valueAttribute = valueElement.Attribute(attributeName);

      if (valueAttribute == null)
        return null;

      return (string)valueAttribute;
    }
  }
}